package com.game.login.service;

import com.baomidou.mybatisplus.toolkit.CollectionUtils;
import com.game.framework.common.model.AccountToken;
import com.game.framework.common.utils.JWTUtil;
import com.game.framework.dao.entity.RoleEntity;
import com.game.framework.dao.entity.UserInfoEntity;
import com.game.framework.dao.mapper.RoleMapper;
import com.game.framework.dao.mapper.UserInfoMapper;
import com.game.framework.message.protobuf.BaseProto;
import com.game.framework.message.protobuf.UserProto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    protected RoleMapper roleMapper;

    @Autowired
    protected UserInfoMapper userInfoMapper;
    /**
     * 使用算法，根据用户名生成一个唯的ID
     */
    public String generatePassword(String password) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        //String newValue = MD5Utils.md5Hex(password, MD5_ENCODE);
        //String newPassword = MD5Utils.md5Hex((password + "_" + newValue), MD5_ENCODE);
        return encoder.encode(password);
    }
    public boolean isSmsCodeRight(String code, String account) {
        return true;
    }


    public String createUserToken(String account, Integer userId) {
        AccountToken accountToken = new AccountToken();
        accountToken.setAccount(account);
        accountToken.setUserId(userId);
        accountToken.setExpireDays(30);
        return JWTUtil.createToken(accountToken);
    }

    public RoleEntity createPlayerRole(UserInfoEntity userInfo) {
        RoleEntity roleEntity = new RoleEntity();
        roleEntity.setRoleId(System.currentTimeMillis()+ RandomUtils.nextLong());
        roleEntity.setUserId(userInfo.getUserCode());
        roleEntity.setNickName(userInfo.getNickName());
        roleEntity.setHeadImg(userInfo.getHeadimgUrl());
        roleEntity.setCreateTime(roleEntity.getCreateTime());
        roleEntity.setLastLoginTime(new Date());
        roleEntity.setNewCreate(true);
        roleMapper.insert(roleEntity);
        roleEntity = roleMapper.selectByRoleId(roleEntity.getRoleId());
        return roleEntity;
    }

    public UserProto.UserInfo.Builder generateUserInfo(UserInfoEntity userEntity) {
        UserProto.UserInfo.Builder userInfo = UserProto.UserInfo.newBuilder()
                .setAccount(userEntity.getPhone())
                .setUserId(userEntity.getUserCode())
                .setTenantId(userEntity.getTenantId())
                .setPhone(userEntity.getPhone())
                .setNickName(userEntity.getNickName())
                .setRealName(userEntity.getRealName())
                .setPersonSign(userEntity.getPersonSign())
                .setSex(userEntity.getSex())
                .setHeadimgUrl(userEntity.getHeadimgUrl())
                .setCity(userEntity.getCity())
                .setCountry(userEntity.getCountry())
                .setProvince(userEntity.getProvince())
                .setEmail(userEntity.getEmail())
                .setCardNo(userEntity.getCardNo())
                .setCardImg1(userEntity.getCardImg1())
                .setCardImg2(userEntity.getCardImg2())
                .setRealed(userEntity.getRealed())
                .setParentId(userEntity.getParentId())
                .setInvitationCode(userEntity.getInvitationCode())
                .setAppType(userEntity.getAppType())
                .setAppId(userEntity.getAppId())
                .setUserGrade(userEntity.getUserGrade())
                .setPointsCurrent(userEntity.getUserGrade())
                .setBankCard(userEntity.getBankCard())
                .setBankName(userEntity.getBankName())
                .setBankCardType(userEntity.getBankCardType())
                .setBrandSide(userEntity.getBrandSide())
                .setAliAccount(userEntity.getAliAccount())
                .setWalletToken(userEntity.getWalletToken())
                .setVersion(userEntity.getVersion());
        if(ObjectUtils.isNotEmpty(userEntity.getCreateTime())) {
            userInfo.setCreateTime(userEntity.getCreateTime().getTime());
        }
        if(ObjectUtils.isNotEmpty(userEntity.getUpdateTime())) {
            userInfo.setUpdateTime(userEntity.getUpdateTime().getTime());
        }
        return userInfo;
    }

    public UserProto.RoleInfo.Builder generateRoleInfo(RoleEntity roleEntity) {
        UserProto.RoleInfo.Builder roleInfo = UserProto.RoleInfo.newBuilder()
                .setRoleId(roleEntity.getRoleId())
                .setNickName(roleEntity.getNickName())
                .setHeadImg(roleEntity.getHeadImg())
                .setLevel(roleEntity.getLevel())
                .setGold(roleEntity.getGold())
                .setScore(roleEntity.getScore())
                .setTicket(roleEntity.getTicket())
                .setDragon(roleEntity.getDragon())
                .setPole(roleEntity.getPole())
                .setBait(roleEntity.getBait())
                .setNewCreate(roleEntity.isNewCreate()?1:0);
        if(ObjectUtils.isNotEmpty(roleEntity.getCreateTime())) {
            roleInfo.setCreateTime(roleEntity.getCreateTime().getTime());
        }
        if(ObjectUtils.isNotEmpty(roleEntity.getLastLoginTime())) {
            roleInfo.setLastLoginTime(roleEntity.getLastLoginTime().getTime());
        }
        if(ObjectUtils.isNotEmpty(roleEntity.getLastLogoutTime())) {
            roleInfo.setLastLogoutTime(roleEntity.getLastLoginTime().getTime());
        }
        return roleInfo;
    }
    @Override
    public BaseProto.ErrorCode login(UserProto.LoginRequest request, UserProto.LoginResponse.Builder response) {
        String account = "";
        if (StringUtils.isNotEmpty(request.getAccount())) {
            account = request.getAccount();
        }else if (StringUtils.isNotEmpty(request.getPhone())){
            account = request.getPhone();
        }else{
            return BaseProto.ErrorCode.ACCOUNT_NOT_EXIST;
        }
        try {
            UserInfoEntity userInfoEntity = userInfoMapper.selectByPhone(account);
            if (userInfoEntity == null) {
                return BaseProto.ErrorCode.ACCOUNT_NOT_EXIST;
            }
            if (StringUtils.isNotEmpty(request.getPassword())) {
                String password = this.generatePassword(request.getPassword());
                boolean isRight = password.equals(userInfoEntity.getPassword());
                if (!isRight) {
                    //返回登陆异常
                    return BaseProto.ErrorCode.PASSWORD_ERROR;
                }
            } else if (StringUtils.isNotEmpty(request.getSmsCode())) {
                boolean isRight = isSmsCodeRight(request.getSmsCode(), account);
                if (!isRight) {
                    return BaseProto.ErrorCode.SMS_CODE_ERROR;
                }
            }
            UserProto.UserInfo.Builder userInfo = generateUserInfo(userInfoEntity);
            List<UserProto.RoleInfo> roleInfoList = new ArrayList<>();
            List<RoleEntity> roleEntityList = roleMapper.selectByUserId((long) userInfoEntity.getUserCode());
            if (CollectionUtils.isNotEmpty(roleEntityList)) {
                for (RoleEntity roleEntity : roleEntityList) {
                    UserProto.RoleInfo.Builder roleInfo = generateRoleInfo(roleEntity);
                    roleInfoList.add(roleInfo.build());
                }
            } else {
                RoleEntity roleEntity = createPlayerRole(userInfoEntity);
                UserProto.RoleInfo.Builder roleInfo = generateRoleInfo(roleEntity);
                roleInfoList.add(roleInfo.build());
            }
            String token = createUserToken(userInfoEntity.getPhone(), userInfoEntity.getUserCode());

             response.setToken(token)
                     .setUser(userInfo)
                     .addAllRoles(roleInfoList);
            return BaseProto.ErrorCode.SUCCESS;
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return BaseProto.ErrorCode.UNKNOWN_ERROR;
    }

    @Override
    public BaseProto.ErrorCode createRole(UserProto.CreateRoleRequest request, UserProto.CreateRoleResponse.Builder response) {
        try {
            UserInfoEntity userInfoEntity = userInfoMapper.selectByUserCode((int) request.getUserId());
            if (userInfoEntity != null) {
                RoleEntity roleEntity = createPlayerRole(userInfoEntity);
                UserProto.RoleInfo.Builder roleInfo = generateRoleInfo(roleEntity);
                response.setUserId(request.getUserId())
                        .setRole(roleInfo);
                return BaseProto.ErrorCode.SUCCESS;
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return BaseProto.ErrorCode.UNKNOWN_ERROR;
    }

    @Override
    public BaseProto.ErrorCode updateRole(UserProto.UpdateRoleRequest request, UserProto.UpdateRoleResponse.Builder response) {
        try {
            RoleEntity roleEntity = roleMapper.selectByRoleId(request.getRoleId());
            if (ObjectUtils.isNotEmpty(roleEntity)) {
                if (ObjectUtils.isNotEmpty(request.getNickName())) {
                    roleEntity.setNickName(request.getNickName());
                }
                if (ObjectUtils.isNotEmpty(request.getHeadImg())) {
                    roleEntity.setHeadImg(request.getHeadImg());
                }
                if (ObjectUtils.isNotEmpty(request.getLevel())) {
                    roleEntity.setLevel(request.getLevel());
                }
                if (ObjectUtils.isNotEmpty(request.getGold())) {
                    roleEntity.setGold(request.getGold());
                }
                if (ObjectUtils.isNotEmpty(request.getScore())) {
                    roleEntity.setScore(request.getScore());
                }
                if (ObjectUtils.isNotEmpty(request.getTicket())) {
                    roleEntity.setTicket(request.getTicket());
                }
                if (ObjectUtils.isNotEmpty(request.getDragon())) {
                    roleEntity.setDragon(request.getDragon());
                }
                if (ObjectUtils.isNotEmpty(request.getPole())) {
                    roleEntity.setPole(request.getPole());
                }
                if (ObjectUtils.isNotEmpty(request.getBait())) {
                    roleEntity.setBait(request.getBait());
                }
                roleMapper.updateById(roleEntity);
                response.setUserId(roleEntity.getUserId())
                        .setRoleId(roleEntity.getRoleId())
                        .setResult(1);
                return BaseProto.ErrorCode.SUCCESS;
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return BaseProto.ErrorCode.UNKNOWN_ERROR;
    }

    @Override
    public BaseProto.ErrorCode getUserInfo(UserProto.GetUserInfoRequest request, UserProto.GetUserInfoResponse.Builder response) {
        try {
            UserInfoEntity userInfoEntity = userInfoMapper.selectByUserCode((int) request.getUserId());
            if (userInfoEntity != null) {
                UserProto.UserInfo.Builder userInfo = generateUserInfo(userInfoEntity);
                response.setUser(userInfo);
                return BaseProto.ErrorCode.SUCCESS;
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return BaseProto.ErrorCode.UNKNOWN_ERROR;
    }

    @Override
    public BaseProto.ErrorCode getRoleInfo(UserProto.GetRoleInfoRequest request, UserProto.GetRoleInfoResponse.Builder response) {
        try {
            RoleEntity roleEntity = roleMapper.selectByRoleId(request.getRoleId());
            if (ObjectUtils.isNotEmpty(roleEntity)) {
                UserProto.RoleInfo.Builder roleInfo = generateRoleInfo(roleEntity);
                response.setUserId(request.getUserId())
                        .setRole(roleInfo);
                return BaseProto.ErrorCode.SUCCESS;
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return BaseProto.ErrorCode.UNKNOWN_ERROR;
    }

    @Override
    public BaseProto.ErrorCode enterGame(UserProto.EnterGameRequest request, UserProto.EnterGameResponse.Builder response) {
        return BaseProto.ErrorCode.SUCCESS;
    }

    @Override
    public BaseProto.ErrorCode exitGame(UserProto.ExitGameRequest request, UserProto.ExitGameResponse.Builder response) {
        return BaseProto.ErrorCode.SUCCESS;
    }

    @Override
    public void test(){
//        if(userInfoMapper == null){
//            log.error("userInfoMapper is not start!!!!");
//            userInfoMapper = applicationContext.getBean(UserInfoMapper.class);
//        }
//        UserInfoEntity userInfoEntity = userInfoMapper.selectByPhone("17521104340");
//        if (userInfoEntity != null){
//            log.info(userInfoEntity.toString());
//        }
//        if(roleMapper == null){
//            roleMapper = applicationContext.getBean(RoleMapper.class);
//        }
//        long userid = 296;
//        List<RoleEntity> roleEntityList = roleMapper.selectByUserId(userid);
//        if (roleEntityList != null){
//            log.info(roleEntityList.toString());
//        }
//        UserProto.LoginRequest request = UserProto.LoginRequest.newBuilder().setPhone("17521104340").setSmsCode("1234").build();
//        UserProto.LoginResponse.Builder response = UserProto.LoginResponse.newBuilder();
//        BaseProto.ErrorCode errorCode = login(request, response);
//        ByteString resBody = response.build().toByteString();
//        log.info(resBody.toString());
    }


}
